﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using TSL_Tools.SqlTools;
using System.IO;
using System.Windows.Threading;
using VSLT_ReportingEngine;
using System.Data;

namespace VSLT_Reporting_UI
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        #region -- Public Properties ----------------------------------------------------
        public static readonly string Msg_DATABASEUPDATEINFORMATION = @"Visual Studio Load Test database ({0}) was updated.\r\nCleaned up and added the following items:\r\n{1}";
        public static string reportingEngineVersion = "6.0.0.1 Beta";
        public int currentlySelectedRunId { get; set; }
        #endregion

        #region -- Private Properties ---------------------------------------------------
        ReportingEngine re;
        #endregion

        #region -- Constructors ---------------------------------------------------------
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            re = new ReportingEngine(reportingEngineVersion);
            tbSqlConn.Text = re.sqlConnection;
            currentlySelectedRunId = -1;
        }
        #endregion

        #region -- Event Methods --------------------------------------------------------
        private void btnClose_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void btnUpdateDb_Click(object sender, RoutedEventArgs e)
        {
            if (re.GetReportingEngineVersion(reportingEngineVersion))
            {
                if (MessageBox.Show("The version of reporting objects in the DB appear to be the latest version. Are you sure you want to update the database?", "Confirm", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                {
                    PerformDbUpdate();
                }
            }
            else
            {
                if (MessageBox.Show("It appears as though you do not have the latest version of the reporting tool objects installed. Do you want to install them now?", "Confirm", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                {
                    PerformDbUpdate();
                }
            }
        }

        private void btnUpdaTablesDb_Click(object sender, RoutedEventArgs e)
        {
            if (!re.GetReportingEngineVersion("6.0.0.1 Beta"))
            {
                if(MessageBox.Show("It appears as though you do not have the latest version of the reporting tool objects installed. Do you want to install them now?", "Confirm", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                {
                    PerformDbUpdate();
                }
            }
            else
            {
                System.Windows.Input.Cursor _cursor = this.Cursor;
                this.Cursor = Cursors.Wait;

                string sUpdated = re.UpdateTheDataWarehouseTables();

                tsslMessage.Content = sUpdated;
                tsslMessage.Refresh();
                this.Cursor = _cursor;
            }
        }

        private void tbSqlConn_TextChanged(object sender, TextChangedEventArgs e)
        {
            re.sqlConnection = tbSqlConn.Text;
        }

        private void btnGetRuns_Click(object sender, RoutedEventArgs e)
        {
            dgMainResults.ItemsSource = re.GetListOfCompletedRuns().AsDataView();
            tabListOfRuns.IsSelected = true;
        }

        private void btnGetIntervals_Click(object sender, RoutedEventArgs e)
        {
            if(currentlySelectedRunId == -1)
            {
                MessageBox.Show("You need to highlight a run in order to get the intervals.", "Input Needed", MessageBoxButton.OK, MessageBoxImage.Asterisk);
                return;
            }
            GetAllIntervals();
        }

        private void btnGetResults_Click(object sender, RoutedEventArgs e)
        {
            re.AddConstantLoadIntervals();
        }
        #endregion

        #region -- Private Methods ------------------------------------------------------
        private void PerformDbUpdate()
        {
            System.Windows.Input.Cursor _cursor = this.Cursor;
            this.Cursor = Cursors.Wait;
            StringBuilder sb = new StringBuilder();

            tsslMessage.Content = "Clearing Old Objects";
            tsslMessage.Refresh();
            re.CleanupOldSql(ref sb);

            tsslMessage.Content = "Adding New Objects";
            tsslMessage.Refresh();
            re.AddNewSql(ref sb);

            tsslMessage.Content = "Updating Warehousing Data Tables";
            tsslMessage.Refresh();
            sb.Append(re.UpdateTheDataWarehouseTables());
            
            tsslMessage.Content = "Update Completed";
            tsslMessage.Refresh();
            this.Cursor = _cursor;
            tbResults.Text = String.Format(Msg_DATABASEUPDATEINFORMATION, "LoadTest2010", sb.ToString());
        }

        private void GetAllIntervals()
        {
            MessageBoxResult result = MessageBox.Show("This process can take several minutes. Do yoiu wish to proceed?", "Continue?", MessageBoxButton.YesNo, MessageBoxImage.Question);
            if(result == MessageBoxResult.No)
            {
                return;
            }
            System.Windows.Input.Cursor _cursor = this.Cursor;
            this.Cursor = Cursors.Wait;

            DataSet resultSet = re.GetAllIntervalsForRun(currentlySelectedRunId);

            foreach(DataTable table in resultSet.Tables)
            {
                //Create the title block
                string title = String.Format("{0} Users: {1} - {2} Seconds"
                    , table.Rows[0]["User Count"]
                    , table.Rows[0]["Start Offset"]
                    , table.Rows[0]["End Offset"]);
                TextBlock tb = new TextBlock();
                tb.Text = title;
                tb.FontSize = 18.667;
                tb.FontWeight = System.Windows.FontWeights.Bold;
                tb.HorizontalAlignment = HorizontalAlignment.Center;
                ThicknessConverter tc = new ThicknessConverter();
                tb.Margin = (Thickness)tc.ConvertFromString("5");
                tb.Background = Brushes.BlanchedAlmond;
                spIntervalResults.Children.Add(tb);

                // Add the DataGrid
                DataGrid myGrid = new DataGrid();
                myGrid.Margin = (Thickness)tc.ConvertFromString("5");
                myGrid.ItemsSource = table.DefaultView;
                spIntervalResults.Children.Add(myGrid);
            }
            this.Cursor = _cursor;
            tabIntervalResults.IsSelected = true;
        }
        #endregion

        private void dgMainResults_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if(dgMainResults.SelectedItem == null)
            {
                currentlySelectedRunId = -1;
                return;
            }
            foreach (object obj in dgMainResults.SelectedItems)
            {
                DataRowView row = (DataRowView)obj;
                {
                    int _runId;
                    Int32.TryParse(row[0].ToString(), out _runId);
                    currentlySelectedRunId = _runId;
                }
            }
        }
    }
    
    /// <summary>
    /// This extension is used to force an update of the status bar messages in real time so that the messages for DB actions are reported as they occur.
    /// </summary>
    public static class ExtensionMethods
    {
        private static Action EmptyDelegate = delegate() { };

        public static void Refresh(this UIElement uiElement)
        {
            uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
        }
    }
}
